package cn.nexttec.noteplayer.ui.widget.image_editor

import android.content.Context
import android.graphics.*
import android.view.MotionEvent
import android.view.View
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import cn.nexttec.noteplayer.ui.widget.PopupDialog
import kotlin.math.*

class CutOverlayView(context: Context) : View(context) {

    private var isCutMode = false

    private val overlayPaint = Paint().apply {
        color = Color.parseColor("#88000000")
    }
    private val clearPaint = Paint().apply {
        xfermode = PorterDuffXfermode(PorterDuff.Mode.CLEAR)
    }
    private val borderPaint = Paint().apply {
        color = Color.WHITE
        strokeWidth = 4f
        style = Paint.Style.STROKE
        isAntiAlias = true
    }
    private val handlePaint = Paint().apply {
        color = Color.WHITE
        style = Paint.Style.FILL
        isAntiAlias = true
    }
    private val textPaint = Paint().apply {
        color = Color.WHITE
        textSize = 60f
        isAntiAlias = true
        typeface = Typeface.DEFAULT_BOLD
        textAlign = Paint.Align.CENTER
    }

    private var cutRect: RectF? = null
    private val handleRadius = 30f

    private var startX = 0f
    private var startY = 0f

    private val closeBtnRect = RectF()
    private val okBtnRect = RectF()
    private val btnSize = 100f
    private val btnPadding = 20f

    interface CutListener {
        fun onCutConfirmed(cutRect: RectF)
    }

    private var cutListener: CutListener? = null

    fun setCutListener(listener: CutListener) {
        this.cutListener = listener
    }

    private enum class TouchArea {
        NONE, TOP_LEFT, TOP_RIGHT, BOTTOM_LEFT, BOTTOM_RIGHT, MOVE, CLOSE_BTN, OK_BTN
    }
    private var currentTouchArea = TouchArea.NONE
    private var lastTouchX = 0f
    private var lastTouchY = 0f

    fun enableCutMode(enable: Boolean) {
        isCutMode = enable
        currentTouchArea = TouchArea.NONE
        cutRect = null
        invalidate()
    }

    override fun onDraw(canvas: Canvas) {
        if (!isCutMode) return

        val saved = canvas.saveLayer(0f, 0f, width.toFloat(), height.toFloat(), null)
        canvas.drawRect(0f, 0f, width.toFloat(), height.toFloat(), overlayPaint)

        cutRect?.let { rect ->
            canvas.drawRect(rect, clearPaint)
            canvas.drawRect(rect, borderPaint)
            drawHandle(canvas, rect.left, rect.top)
            drawHandle(canvas, rect.right, rect.top)
            drawHandle(canvas, rect.left, rect.bottom)
            drawHandle(canvas, rect.right, rect.bottom)
        }

        val closeX = btnPadding + btnSize / 2
        val closeY = btnPadding + btnSize / 2
        closeBtnRect.set(closeX - btnSize / 2, closeY - btnSize / 2, closeX + btnSize / 2, closeY + btnSize / 2)
        canvas.drawText("×", closeX, closeY + textPaint.textSize / 3, textPaint)

        val okX = width - btnPadding - btnSize / 2
        val okY = btnPadding + btnSize / 2
        okBtnRect.set(okX - btnSize / 2, okY - btnSize / 2, okX + btnSize / 2, okY + btnSize / 2)
        canvas.drawText("✔", okX, okY + textPaint.textSize / 3, textPaint)

        canvas.restoreToCount(saved)
    }

    private fun drawHandle(canvas: Canvas, cx: Float, cy: Float) {
        canvas.drawCircle(cx, cy, handleRadius, handlePaint)
    }

    override fun onTouchEvent(event: MotionEvent): Boolean {
        if (!isCutMode) return false

        val x = event.x
        val y = event.y

        when (event.action) {
            MotionEvent.ACTION_DOWN -> {
                if (closeBtnRect.contains(x, y)) {
                    currentTouchArea = TouchArea.CLOSE_BTN
                    return true
                }
                if (okBtnRect.contains(x, y)) {
                    currentTouchArea = TouchArea.OK_BTN
                    return true
                }
                cutRect?.let {
                    if (isInsideHandle(x, y, it.left, it.top)) currentTouchArea = TouchArea.TOP_LEFT
                    else if (isInsideHandle(x, y, it.right, it.top)) currentTouchArea = TouchArea.TOP_RIGHT
                    else if (isInsideHandle(x, y, it.left, it.bottom)) currentTouchArea = TouchArea.BOTTOM_LEFT
                    else if (isInsideHandle(x, y, it.right, it.bottom)) currentTouchArea = TouchArea.BOTTOM_RIGHT
                    else if (it.contains(x, y)) currentTouchArea = TouchArea.MOVE
                    else {
                        startX = x
                        startY = y
                        cutRect = RectF(startX, startY, startX, startY)
                        currentTouchArea = TouchArea.BOTTOM_RIGHT
                    }
                } ?: run {
                    startX = x
                    startY = y
                    cutRect = RectF(startX, startY, startX, startY)
                    currentTouchArea = TouchArea.BOTTOM_RIGHT
                }
                lastTouchX = x
                lastTouchY = y
                invalidate()
                return true
            }
            MotionEvent.ACTION_MOVE -> {
                cutRect?.let {
                    when (currentTouchArea) {
                        TouchArea.MOVE -> {
                            val dx = x - lastTouchX
                            val dy = y - lastTouchY
                            it.offset(dx, dy)
                            lastTouchX = x
                            lastTouchY = y
                        }
                        TouchArea.TOP_LEFT -> {
                            it.left = x
                            it.top = y
                        }
                        TouchArea.TOP_RIGHT -> {
                            it.right = x
                            it.top = y
                        }
                        TouchArea.BOTTOM_LEFT -> {
                            it.left = x
                            it.bottom = y
                        }
                        TouchArea.BOTTOM_RIGHT -> {
                            it.right = x
                            it.bottom = y
                        }
                        else -> {}
                    }
                }
                invalidate()
                return true
            }
            MotionEvent.ACTION_UP -> {
                when (currentTouchArea) {
                    TouchArea.CLOSE_BTN -> enableCutMode(false)
                    TouchArea.OK_BTN -> showConfirmDialog()
                    else -> {}
                }
                currentTouchArea = TouchArea.NONE
                invalidate()
                return true
            }
        }
        return super.onTouchEvent(event)
    }

    private fun isInsideHandle(x: Float, y: Float, cx: Float, cy: Float): Boolean {
        return hypot(x - cx, y - cy) <= handleRadius * 1.5f
    }

    private fun showConfirmDialog() {
        PopupDialog.showAlertDialog("是否要剪裁该区域，确定剪裁后不能恢复，将加载剪裁后的图像？", onConfirm = {
            cutListener?.onCutConfirmed(cutRect!!)
        }, onCancel = {})
    }

    fun getCutRect(): RectF? = cutRect
}
